program write_tp_10km_climate

  use netcdf
  use flogger
  use mongof_common_mod
  use utils_mod

  implicit none

  character(30) mongo_uri
  character(30) mongo_db
  character(30) mongo_col
  character(256) data_file_path
  character(256) wdir_freq_file_path
  character(256) wsp_freq_file_path
  integer cid, nlon, nlat, nlev, nband_wdir_freq, nband_wsp_freq
  real(8), allocatable, dimension(:) :: lon, lat, lev, band_wdir_freq, band_wsp_freq
  real(8), allocatable, dimension(  :,:,:) :: t, pres, q, wsp, wpd
  real(8), allocatable, dimension(:,:,:,:) :: wdir_freq, wsp_freq

  real(8), allocatable, dimension(  :,:,:) :: t2, pres2, q2, wsp2, wpd2
  real(8), allocatable, dimension(:,:,:,:) :: wdir_freq2, wsp_freq2

  real(8) timestamp

  integer i, j, k

  interface
    integer function write_data_zlev(cid, timestamp, nlon, nlat, nlev, nband_wdir_freq, nband_wsp_freq, &
                                     t, pres, q, wsp, wpd, wdir_freq, wsp_freq) result(res) bind(c, name='write_data_zlev')
      use iso_c_binding
      integer(c_int), intent(in), value :: cid
      real(c_double), intent(in), value :: timestamp
      integer(c_int), intent(in), value :: nlon
      integer(c_int), intent(in), value :: nlat
      integer(c_int), intent(in), value :: nlev
      integer(c_int), intent(in), value :: nband_wdir_freq
      integer(c_int), intent(in), value :: nband_wsp_freq
      real(c_double), intent(in) :: t                        (nlev,nlon,nlat)
      real(c_double), intent(in) :: pres                     (nlev,nlon,nlat)
      real(c_double), intent(in) :: q                        (nlev,nlon,nlat)
      real(c_double), intent(in) :: wsp                      (nlev,nlon,nlat)
      real(c_double), intent(in) :: wpd                      (nlev,nlon,nlat)
      real(c_double), intent(in) :: wdir_freq(nband_wdir_freq,nlev,nlon,nlat)
      real(c_double), intent(in) :: wsp_freq (nband_wsp_freq ,nlev,nlon,nlat)
    end function write_data_zlev
  end interface

  call get_command_argument(1, mongo_uri)
  call get_command_argument(2, data_file_path)
  call get_command_argument(3, wdir_freq_file_path)
  call get_command_argument(4, wsp_freq_file_path)

  mongo_uri = 'mongodb://' // trim(mongo_uri) // char(0)
  mongo_db = 'hntp' // char(0)
  mongo_col = 'tp_10km_climate' // char(0)

  call handle_mongo_error(mongoc_connect(mongo_uri, mongo_db, mongo_col, cid), __FILE__, __LINE__)

  call handle_mongo_error(mongoc_create_data_index(cid), __FILE__, __LINE__)

  call read_grid(data_file_path, nlon, nlat, nlev, lon, lat, lev)

  call read_band(wdir_freq_file_path, nband_wdir_freq, band_wdir_freq)
  call read_band(wsp_freq_file_path , nband_wsp_freq , band_wsp_freq )

  allocate(t                        (nlon,nlat,nlev))
  allocate(pres                     (nlon,nlat,nlev))
  allocate(q                        (nlon,nlat,nlev))
  allocate(wsp                      (nlon,nlat,nlev))
  allocate(wpd                      (nlon,nlat,nlev))
  allocate(wdir_freq(nband_wdir_freq,nlon,nlat,nlev))
  allocate(wsp_freq (nband_wsp_freq ,nlon,nlat,nlev))

  call log_notice('Reading data ...')
  call read_data_3d(data_file_path, 't'    , t        )
  call read_data_3d(data_file_path, 'pres' , pres     )
  call read_data_3d(data_file_path, 'q'    , q        )
  call read_data_3d(data_file_path, 'wsp'  , wsp      )
  call read_data_3d(data_file_path, 'wpd'  , wpd      )
  call read_data_4d(wdir_freq_file_path, 'wdir_freq', wdir_freq)
  call read_data_4d(wsp_freq_file_path , 'wsp_freq' , wsp_freq )

  ! Reorganize array dimension to put lon and lat to right.
  call log_notice('Reorganize array dimensions.')
  allocate(t2        (nlev,nlon,nlat))
  allocate(pres2     (nlev,nlon,nlat))
  allocate(q2        (nlev,nlon,nlat))
  allocate(wsp2      (nlev,nlon,nlat))
  allocate(wpd2      (nlev,nlon,nlat))
  allocate(wdir_freq2(nband_wdir_freq,nlev,nlon,nlat))
  allocate(wsp_freq2 (nband_wsp_freq, nlev,nlon,nlat))

  do j = 1, nlat
    do i = 1, nlon
      t2          (:,i,j) = t          (i,j,:)
      pres2       (:,i,j) = pres       (i,j,:)
      q2          (:,i,j) = q          (i,j,:)
      wsp2        (:,i,j) = wsp        (i,j,:)
      wpd2        (:,i,j) = wpd        (i,j,:)
      wdir_freq2(:,:,i,j) = wdir_freq(:,i,j,:)
      wsp_freq2 (:,:,i,j) = wsp_freq (:,i,j,:)
    end do
  end do

  deallocate(t, pres, q, wsp, wdir_freq, wsp_freq)

  call log_notice('Start to write database.')
  call log_notice('Set timestamp to 2019-01-01T00:00.')
  timestamp = 1546300800.0
  call handle_mongo_error(write_data_zlev(cid, timestamp, nlon, nlat, nlev, nband_wdir_freq, nband_wsp_freq, &
                                          t2, pres2, q2, wsp2, wpd2, wdir_freq2, wsp_freq2), __FILE__, __LINE__)

  call mongoc_final()

  deallocate(lon, lat, lev, band_wdir_freq, band_wsp_freq)
  deallocate(t2, pres2, q2, wsp2, wpd2, wdir_freq2, wsp_freq2)

contains

  subroutine read_band(file_path, nband, band)

    character(*), intent(in) :: file_path
    integer, intent(inout) :: nband
    real(8), intent(inout), allocatable :: band(:)

    integer ierr, ncid, dimid, varid

    call handle_netcdf_error(nf90_open(file_path, ior(nf90_noclobber, nf90_64bit_offset), ncid), __file__, __line__)
    call handle_netcdf_error(nf90_inq_dimid(ncid, 'band', dimid), __file__, __line__)
    call handle_netcdf_error(nf90_inquire_dimension(ncid, dimid, len=nband), __file__, __line__)

    allocate(band(nband))

    call handle_netcdf_error(nf90_inq_varid(ncid, 'band', varid), __file__, __line__)
    call handle_netcdf_error(nf90_get_var(ncid, varid, band), __file__, __line__)
    call handle_netcdf_error(nf90_close(ncid), __file__, __line__)

  end subroutine read_band

end program write_tp_10km_climate
